package com.tvunetworks.center.user.controller.api;

import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.constant.UserApiConstant;
import com.tvunetworks.center.user.model.param.api.AccessSessionParam;
import com.tvunetworks.center.user.model.param.api.ListBookingChannelParam;
import com.tvunetworks.center.user.model.param.api.ListGroupParam;
import com.tvunetworks.center.user.model.vo.UserApiParam;
import com.tvunetworks.center.user.model.vo.api.ListGroupVo;
import com.tvunetworks.center.user.service.UserApiService;
import com.tvunetworks.center.user.util.HttpRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xml.sax.InputSource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringReader;

/**
 * @program: tvucc-aggregator
 * @description: user对外api
 * @author Kevin_Li
 * @create: 2019-10-10 18:36
 **/
@Slf4j
@Controller
@RequestMapping(value = {"openapi/cc/${openApiVersion}/user", "openapi/${openApiVersion}/user"})
public class UserApiController {

    @Autowired
    private UserApiService userApiService;

    /**
     *
     * @param param param
     * @return Result
     */
    @PostMapping("/accessSession")
    @ResponseBody
    public Result accessSession(@RequestBody AccessSessionParam param) {
        String session = userApiService.accessSession(param);
        return ResultUtil.success(session);
    }

    /**
     *
     * @param param param
     * @return Result
     */
    @PostMapping("/listGroup")
    @ResponseBody
    public Result listGroup(@RequestBody ListGroupParam param) {
        param.format();
        PageInfo<ListGroupVo> pageInfo = userApiService.listGroup(param);
        return ResultUtil.success(pageInfo);
    }

    /**
     *
     * @param param param
     * @return Result
     */
    @PostMapping("/listBookingR")
    @ResponseBody
    public Result listBookingChannel(@RequestBody ListBookingChannelParam param) {
        PageInfo<Device> pageInfo = userApiService.listBookingChannel(param);
        return ResultUtil.success(pageInfo);
    }

    /**
     *
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/getSession")
    public void getDeviceList(HttpServletRequest request, HttpServletResponse response) {
        UserApiParam userApiParam = new UserApiParam();
        Result<Object> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.info("[Grid API][GetSession][Request data:]" + requestdata);
            //判断参数为xml还是json
            if (!checkParam(userApiParam, request, requestdata, result)){
                return;
            }
            result = userApiService.getSession(userApiParam);
        } catch (Exception e) {
            log.error(e.toString(), e);
        } finally {
            this.response(response, result, userApiParam.getType(), "getSession");
        }
    }

    /**
     *
     * @param request request
     * @param response response
     */
    @PostMapping(value = "/addExt")
    public void addExt(HttpServletRequest request, HttpServletResponse response) {
        UserApiParam userApiParam = new UserApiParam();
        Result<Object> result = null;
        try {
            String requestdata = HttpRequestUtil.getRequestDate(request);
            log.info("[Grid API][addExt][Request data:]" + requestdata);
            //判断参数为xml还是json
//            if (!checkParam(userApiParam, request, requestdata, result)){
//                return;
//                }

            if ("application/xml".equals(request.getContentType())) {
                //xml参数
                try {
                    this.analysisXml(requestdata, userApiParam);
                } catch (Exception e) {
                    log.error(e.toString(), e);
                    result = ResultUtil.error("81000018", "xml analysis exception");
                    userApiParam.setType(UserApiConstant.XML_PARAM);

                }
                userApiParam.setType(UserApiConstant.XML_PARAM);
            } else {
                //json参数
                try {
                    userApiParam = JsonUtil.toObject(requestdata, UserApiParam.class);
                } catch (Exception e) {
                    log.error(e.toString(), e);
                    userApiParam.setType(UserApiConstant.JSON_PARAM);
                }
                userApiParam.setType(UserApiConstant.JSON_PARAM);
            }
            userApiParam.setIp(HttpRequestUtil.getIpAddress(request));
            result = userApiService.addExt(userApiParam);
        } catch (Exception e) {
            log.error(e.toString(), e);
        } finally {
            this.response(response, result, userApiParam.getType(), "addExt");
        }
    }

    private boolean checkParam(UserApiParam userApiParam, HttpServletRequest request, String requestdata, Result<Object> result) {
        //判断参数为xml还是json
        if ("application/xml".equals(request.getContentType())) {
            //xml参数
            try {
                userApiParam = this.analysisXml(requestdata, userApiParam);
            } catch (Exception e) {
                log.error(e.toString(), e);
                ResultUtil.error("81000018", "xml analysis exception");
                userApiParam.setType(UserApiConstant.XML_PARAM);
                return false;
            }
            userApiParam.setType(UserApiConstant.XML_PARAM);
        } else {
            //json参数
            try {
                UserApiParam ua = JsonUtil.toObject(requestdata, UserApiParam.class);
                userApiParam.setEmail(ua.getEmail());
                userApiParam.setPwd(ua.getPwd());
            } catch (Exception e) {
                log.error(e.toString(), e);
                userApiParam.setType(UserApiConstant.JSON_PARAM);
                return false;
            }
            userApiParam.setType(UserApiConstant.JSON_PARAM);
        }
        userApiParam.setIp(HttpRequestUtil.getIpAddress(request));
        return true;
    }

    private UserApiParam analysisXml(String requestdata, UserApiParam userApiParam) throws Exception {
        //解析xml
        if (requestdata != null && requestdata.length() > 0) {
            Element data = null;
            StringReader sr = new StringReader(requestdata);
            InputSource is = new InputSource(sr);
            SAXReader reader = new SAXReader();
            org.dom4j.Document document = reader.read(is);
            //get root Node
            Element root = document.getRootElement();
            userApiParam = analysisXmlAuthData(userApiParam, root);
            data = root.element("Data");
            if (data != null ) {
                String email = null;
                String pwd = null;
                String sessionId = null;
                String extName = null;
                String extUrl = null;
                if (data.element("Email") != null){

                    email = data.element("Email").getStringValue();
                }
                if (data.element("Pwd") != null){

                    pwd = data.element("Pwd").getStringValue();
                }
                if (data.element("SessionId") != null){

                    sessionId = data.element("SessionId").getStringValue();
                }
                if (data.element("ExtName") != null){

                    extName = data.element("ExtName").getStringValue();
                }
                if (data.element("ExtUrl") != null){

                    extUrl = data.element("ExtUrl").getStringValue();
                }
                if (email != null) {
                    userApiParam.setEmail(email);
                }
                if (pwd != null) {
                    userApiParam.setPwd(pwd);
                }
                if (sessionId != null) {
                    userApiParam.setSessionId(sessionId);
                }
                if (extName != null) {
                    userApiParam.setExtName(extName);
                }
                if (extUrl != null) {
                    userApiParam.setExtUrl(extUrl);
                }
            }
        }
        return userApiParam;
    }

    private UserApiParam analysisXmlAuthData(UserApiParam userApiParam, Element root) throws Exception {
        if (root.content().size() != 0) {
            Element appkeyEl = root.element("Appkey");
            Element timestampEl = root.element("Timestamp");
            Element signatureEl = root.element("Signature");
            if (appkeyEl != null) {
                userApiParam.setAppkey(appkeyEl.getStringValue());
            }
            if (timestampEl != null) {
                userApiParam.setTimestamp(timestampEl.getStringValue());
            }
            if (signatureEl != null) {
                userApiParam.setSignature(signatureEl.getStringValue());
            }
            userApiParam.setRequestId(MyUtil.getUUID());
        }
        return userApiParam;
    }


    private void response(HttpServletResponse response, Result<Object> result, String type, String fun) {
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            if (type.equalsIgnoreCase(UserApiConstant.XML_PARAM)) {
                writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                writer.write("<Root>");
                writer.write("<ErrorCode>" + result.getErrorCode() + "</ErrorCode>");
                writer.write("<ErrorInfo>" + result.getErrorInfo() + "</ErrorInfo>");
                if ("addExt".equals(fun)) {
                    writer.write("<SourceId>" + result.getResult() + "</SourceId>");
                } else if ("getSession".equals(fun)) {
                    writer.write("<Data>");
                    if (result.getErrorCode().equals("0x0")) {
                        writer.write("<Data><Session>" + result.getResult() + "</Session></Data>");
                    }
                }
                writer.write("</Root>");
            } else {
                writer.write(JsonUtil.toJsonStr(result));
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
        } finally {
            if (writer!=null){
                writer.flush();
                writer.close();
            }
        }
    }

}
